home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / radiance / nextrad.lha / NeXtRad / hemicube.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-22  |  10.1 KB  |  422 lines

  1. /* hemi-cube.c */
  2. /* written by : Jason R. Wilson   2/21/93 */
  3.  
  4. /* this package provides routines that implement the hemi-cube algorithm
  5.     for form-factor computation */
  6.  
  7. #include <math.h>
  8. #include "render.h"
  9. #include "vector-matrix.h"
  10. #include "hemicube.h"
  11.  
  12. #define HemiRes 100  /* the resolution of the hemi-cube : increase this for more accuracy */
  13. #define HalfRes 50
  14. #define PI 3.141592654
  15.  
  16. /* the hemi-cube itself */
  17.  
  18. HemiPixel   HemiFront [HemiRes][HemiRes];
  19. HemiPixel   HemiRight [HemiRes][HalfRes];
  20. HemiPixel   HemiTop   [HemiRes][HalfRes];
  21. HemiPixel   HemiLeft  [HemiRes][HalfRes];
  22. HemiPixel   HemiBottom[HemiRes][HalfRes];
  23.  
  24. /***********************************************************************/
  25.  
  26. void HemiRenderObjects
  27.    (ObjectCell* ObjectHead,int Case,int winWidth,int winHeight,
  28.     Window ViewWindow)
  29.  
  30. /* This function projects all of the patches (not elements) of the object onto the viewplane*/
  31.  
  32.  
  33. {
  34.  
  35.    EdgeListCell EdgeList[winHeight];
  36.    int loop,loop2;
  37.    PolygonCell *CurrentPoly;
  38.    ObjectCell *Object;
  39.    VisVertexCell *FirstVertex;
  40.    VisVertexCell *Traverse;
  41.    double z,zinc;
  42.    Boolean Gone;
  43.  
  44.    Object = ObjectHead;
  45.  
  46.    while (!(Object == NULL))
  47.    {
  48.  
  49.       /* init. EdgeList */
  50.       for (loop = 0;loop < winHeight;loop++)
  51.      EdgeList[loop].OneHere = false;
  52.       
  53.       /* draw each non-culled polygon */
  54.       
  55.       CurrentPoly = Object->PolygonHead;
  56.       
  57.       while (!(CurrentPoly == NULL))
  58.       {
  59.      if (!(CurrentPoly->Culled == true))
  60.      {
  61.         
  62.         /* clip polygon */
  63.         
  64.         ClipPolygon (CurrentPoly,ViewWindow,&Gone);
  65.         if (!(Gone == true))
  66.         {
  67.            /* rasterize edges of polygon */     
  68.            
  69.            Traverse = CurrentPoly->VisVertices;
  70.            FirstVertex = Traverse;
  71.            
  72.            while (!(Traverse->Next == NULL))
  73.            {
  74.          
  75.           RasterizeEdge (EdgeList,Traverse,
  76.                  Traverse->Next,winWidth,winHeight,ViewWindow);
  77.          Traverse = Traverse->Next;
  78.           
  79.            }
  80.            RasterizeEdge (EdgeList,Traverse,FirstVertex,winWidth,winHeight,
  81.                   ViewWindow);
  82.            /* draw scan lines of polygon */
  83.            
  84.            for (loop = 0;loop < winHeight;loop++)
  85.           if (EdgeList[loop].OneHere == true)
  86.           {
  87.              z = EdgeList[loop].Depth1;
  88.              if (!(EdgeList[loop].Depth2 - EdgeList[loop].Depth1 - 1 == 0))
  89.             zinc = (EdgeList[loop].Depth2 - EdgeList[loop].Depth1)/
  90.                (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
  91.              for (loop2 = EdgeList[loop].Xpos1;loop2 < EdgeList[loop].Xpos2;
  92.               loop2++)
  93.              {
  94.             switch (Case) {
  95.              case 1: 
  96.                if (z < HemiFront[loop2][loop].depth)
  97.                {
  98.                   HemiFront[loop2][loop].depth = z;
  99.                   HemiFront[loop2][loop].ID = CurrentPoly->ID;
  100.                }
  101.                break;
  102.              case 2:
  103.                if (z < HemiRight[loop2][loop].depth)
  104.                {
  105.                   HemiRight[loop2][loop].depth = z;
  106.                   HemiRight[loop2][loop].ID = CurrentPoly->ID;
  107.                }
  108.                break;
  109.              case 3:
  110.                if (z < HemiTop[loop2][loop].depth)
  111.                {
  112.                   HemiTop[loop2][loop].depth = z;
  113.                   HemiTop[loop2][loop].ID = CurrentPoly->ID;
  114.                }
  115.                break;
  116.              case 4:
  117.                if (z < HemiLeft[loop2][loop].depth)
  118.                {
  119.                   HemiLeft[loop2][loop].depth = z;
  120.                   HemiLeft[loop2][loop].ID = CurrentPoly->ID;
  121.                }
  122.                break;
  123.              case 5:
  124.                if (z < HemiBottom[loop2][loop].depth)
  125.                {
  126.                   HemiBottom[loop2][loop].depth = z;
  127.                   HemiBottom[loop2][loop].ID = CurrentPoly->ID;
  128.                }
  129.                break;
  130.                
  131.                z += zinc;
  132.             }
  133.             EdgeList[loop].OneHere = false;
  134.              }
  135.           }
  136.         }
  137.  
  138.      }
  139.      CurrentPoly = CurrentPoly->Next;
  140.       }
  141.       
  142.       Object = Object->Next;
  143.    }
  144. }
  145.  
  146. /***********************************************************************/
  147. void ComputeDeltas ()
  148. /* computes the delta form-factors */
  149.  
  150. {
  151.    int i,j;
  152.    double x,y,z;
  153.    double inc;
  154.    double start;
  155.    double deltaA;
  156.    double sumcheck;
  157.  
  158.    sumcheck = 0.0;
  159.    start = -1.0 + 1.0/HemiRes;
  160.    inc   = 2.0/HemiRes;
  161.    x = start;
  162.    y = start;
  163.    deltaA = inc*inc;
  164.    /* compute the deltas for the front face */
  165.  
  166.    for (j = 0;j < HemiRes;j++)
  167.    {
  168.       for (i = 0;i < HemiRes;i++)
  169.       {           
  170.      HemiFront[i][j].deltaFF = deltaA/(PI*(x*x + y*y + 1)*(x*x + y*y +1));
  171.      x += inc;
  172.      sumcheck += HemiFront[i][j].deltaFF;
  173.       }
  174.       x = start;
  175.       y += inc;
  176.    }
  177.    
  178.    y = start;
  179.    z = 1.0/HemiRes;
  180.    
  181.    for (j = 0;j < HalfRes;j++)
  182.    {
  183.       for (i = 0;i < HemiRes;i++)
  184.       {
  185.      HemiLeft[i][j].deltaFF =z*deltaA/(PI*(y*y + z*z + 1)*(y*y + z*z +1));
  186.      HemiTop[i][j].deltaFF =z*deltaA/(PI*(y*y + z*z + 1)*(y*y + z*z +1));
  187.      HemiRight[i][j].deltaFF =z*deltaA/(PI*(y*y + z*z + 1)*(y*y + z*z +1));
  188.      HemiBottom[i][j].deltaFF=z*deltaA/(PI*(y*y + z*z + 1)*(y*y + z*z +1));
  189.      sumcheck += (4.0*HemiLeft[i][j].deltaFF);
  190.      y += inc;
  191.       }
  192.       y = start;
  193.       z += inc;
  194.    }
  195.    
  196.      
  197. }
  198.  
  199. /***********************************************************************/
  200.  
  201. void InitHemiCube ()
  202.  
  203. /* init. the z-buffer and the ID of the hemi-cube */
  204.  
  205. {
  206.    int loop, loop2;
  207.  
  208.    /* init. front of cube */
  209.  
  210.    for (loop = 0;loop < HemiRes;loop++)
  211.       for (loop2 = 0;loop2 < HemiRes;loop2++)
  212.       {
  213.      HemiFront[loop][loop2].depth = 10000000.0; /* deep enough ? */
  214.      HemiFront[loop][loop2].ID = 0;
  215.       }
  216.  
  217.    /* init. sides of cube */
  218.  
  219.    for (loop = 0;loop < HemiRes;loop++)
  220.       for (loop2 = 0;loop2 < HalfRes;loop2++)
  221.       {
  222.      HemiRight[loop][loop2].depth = 10000000.0; /* ditto */
  223.      HemiRight[loop][loop2].ID = 0;
  224.      HemiTop[loop][loop2].depth = 10000000.0; /* ditto */
  225.      HemiTop[loop][loop2].ID = 0;
  226.      HemiLeft[loop][loop2].depth = 10000000.0; /* ditto */
  227.      HemiLeft[loop][loop2].ID = 0;
  228.      HemiBottom[loop][loop2].depth = 10000000.0; /* ditto */
  229.      HemiBottom[loop][loop2].ID = 0;
  230.       }
  231.  
  232. }
  233.  
  234. /***********************************************************************/
  235.  
  236. void ProjectPatch (PolygonCell *Poly,double *Row)
  237. {
  238.   /* this routine projects all of patches onto the hemi-cube surrounding
  239.      the polygon passed in.  It puts the row of form-factors into Row */
  240.    Point VRP,center;
  241.    int loop2,loop3;
  242.    VertexListCell *traverse;
  243.    int count;
  244.    Vector u,v,n;
  245.    Vector permu,permv,permn;
  246.    Window ViewWindow;
  247.    double eye;
  248.    Matrix HemiTransform;
  249.    
  250.   /* compute the center of the patch in question */
  251.   
  252.   center.x = 0.0;
  253.   center.y = 0.0;
  254.   center.z = 0.0;
  255.   count = 0;
  256.   
  257.   traverse = Poly->Vertices;
  258.   
  259.   while (!(traverse == NULL))
  260.     {
  261.       count++;
  262.       center.x += traverse->Vertex->WorldPosition.x;
  263.       center.y += traverse->Vertex->WorldPosition.y;
  264.       center.z += traverse->Vertex->WorldPosition.z;
  265.       traverse = traverse->Rest;
  266.     }
  267.   
  268.   center.x /= (double)count;
  269.   center.y /= (double)count;
  270.   center.z /= (double)count;
  271.   
  272.   n = Normalize (Poly->Normal);
  273.   
  274.   v.dx = Poly->Vertices->Vertex->WorldPosition.x - center.x;
  275.   v.dy = Poly->Vertices->Vertex->WorldPosition.y - center.y;
  276.   v.dz = Poly->Vertices->Vertex->WorldPosition.z - center.z;
  277.   
  278.   v = Normalize (v);
  279.   u = Cross (n,v);
  280.   eye = -1.0;
  281.   
  282.   permu = u;
  283.   permv = v;
  284.   permn = n;
  285.   
  286.   VRP.x = center.x + n.dx;  /* move VRP up to front face of hemicube */
  287.   VRP.y = center.y + n.dy;
  288.   VRP.z = center.z + n.dz;
  289.   
  290.   InitHemiCube ();
  291.   
  292.   
  293.   /* project down to front of cube */
  294.   
  295.   ProduceTransform (VRP,u,v,n,eye,&HemiTransform);      
  296.   TransformView (ObjectHead,HemiTransform);
  297.   
  298.   
  299.   ViewWindow.Wr = 1.0;
  300.   ViewWindow.Wt = 1.0;
  301.   ViewWindow.Wl = -1.0;
  302.   ViewWindow.Wb = -1.0;
  303.   
  304.   
  305.   CullBackFaces (ObjectHead,eye,VRP,n); 
  306.   HemiRenderObjects (ObjectHead,1,HemiRes,HemiRes,ViewWindow); 
  307.   
  308.   
  309.   /* project down to sides of cube */
  310.   
  311.   ViewWindow.Wb = 0.0; /* only half of a face now */
  312.   
  313.   /* project to right */
  314.   
  315.   
  316.   VRP.x = center.x + permu.dx;  /* move VRP to right side of hemicube */
  317.   VRP.y = center.y + permu.dy;
  318.   VRP.z = center.z + permu.dz;
  319.   
  320.   n = permu;
  321.   u = permv;
  322.   v = permn;
  323.   
  324.   ProduceTransform (VRP,u,v,n,eye,&HemiTransform);      
  325.   TransformView (ObjectHead,HemiTransform);
  326.   CullBackFaces (ObjectHead,eye,VRP,n); 
  327.   
  328.   HemiRenderObjects (ObjectHead,2,HemiRes,HalfRes,ViewWindow);
  329.   
  330.   /* project to top */
  331.   
  332.   
  333.   VRP.x = center.x + (-1)*permv.dx;  /* move VRP to top side of hemicube */
  334.   VRP.y = center.y + (-1)*permv.dy;
  335.   VRP.z = center.z + (-1)*permv.dz;
  336.   
  337.   n = Scale (permv,-1);
  338.   u = permu;
  339.   v = permn;
  340.   
  341.   ProduceTransform (VRP,u,v,n,eye,&HemiTransform);      
  342.   TransformView (ObjectHead,HemiTransform);
  343.   CullBackFaces (ObjectHead,eye,VRP,n); 
  344.   
  345.   HemiRenderObjects (ObjectHead,3,HemiRes,HalfRes,ViewWindow);
  346.       
  347.   /* project to left */
  348.   
  349.   
  350.   VRP.x = center.x + (-1)*permu.dx; /* move VRP to left side of hemicube */
  351.   VRP.y = center.y + (-1)*permu.dy;
  352.   VRP.z = center.z + (-1)*permu.dz;
  353.   
  354.   n = Scale (permu,-1);
  355.   u = Scale (permv,-1);
  356.   v = permn;
  357.   
  358.   ProduceTransform (VRP,u,v,n,eye,&HemiTransform);      
  359.   TransformView (ObjectHead,HemiTransform);
  360.   CullBackFaces (ObjectHead,eye,VRP,n); 
  361.   
  362.   HemiRenderObjects (ObjectHead,4,HemiRes,HalfRes,ViewWindow);
  363.   
  364.   /* project to bottom */
  365.   
  366.   
  367.   VRP.x = center.x + permv.dx; /* move VRP to bot. side of hemicube */
  368.   VRP.y = center.y + permv.dy;
  369.   VRP.z = center.z + permv.dz;
  370.   
  371.   n = permv;
  372.   u = Scale (permu,-1);
  373.   v = permn;
  374.   
  375.   ProduceTransform (VRP,u,v,n,eye,&HemiTransform);      
  376.   TransformView (ObjectHead,HemiTransform);
  377.   CullBackFaces (ObjectHead,eye,VRP,n); 
  378.   
  379.   HemiRenderObjects (ObjectHead,5,HemiRes,HalfRes,ViewWindow);      
  380.   
  381.   /* now go through and sum up the patch-to-patch ff's ! */
  382.   
  383.   
  384.   /* sum front of cube contribution */
  385.   
  386.   for (loop2 = 0;loop2 < HemiRes;loop2++)
  387.     for (loop3 = 0;loop3 < HemiRes;loop3++)
  388.       {
  389.     if (!(HemiFront[loop2][loop3].ID == 0))
  390.       Row[(HemiFront[loop2][loop3].ID)-1] += 
  391.         HemiFront[loop2][loop3].deltaFF;
  392.       }
  393.   
  394.   /* sum sides of cube */
  395.   
  396.   for (loop2 = 0;loop2 < HemiRes;loop2++)
  397.     for (loop3 = 0;loop3 < HalfRes;loop3++)
  398.       {
  399.     if (!(HemiRight[loop2][loop3].ID == 0))
  400.       Row[(HemiRight[loop2][loop3].ID)-1] += 
  401.         HemiRight[loop2][loop3].deltaFF;
  402.     if (!(HemiTop[loop2][loop3].ID == 0))
  403.       Row[(HemiTop[loop2][loop3].ID)-1] += 
  404.         HemiTop[loop2][loop3].deltaFF;
  405.     if (!(HemiLeft[loop2][loop3].ID == 0))
  406.       Row[(HemiLeft[loop2][loop3].ID)-1] += 
  407.         HemiLeft[loop2][loop3].deltaFF;
  408.     if (!(HemiBottom[loop2][loop3].ID == 0))
  409.       Row[(HemiBottom[loop2][loop3].ID)-1] += 
  410.         HemiBottom[loop2][loop3].deltaFF;
  411.       }
  412.   
  413. }
  414.  
  415.  
  416. /*----------------------------------------------------------------------*/
  417.  
  418.  
  419.  
  420.  
  421.  
  422.